#!/usr/bin/env ruby

require 'rubygems'
require 'camping'
require 'net/pop'
require 'action_mailer'
require 'redcloth'

Camping.goes :SpamSack

module SpamSack::Controllers
  class Index < R '/'
    def get
      render :index
    end
  end
  
  class Inbox < R '/inbox/(\w+)'
    def get name
      @inbox = SpamSack::Models::Inbox.find_or_create_by_name(name.downcase)
      render :inbox
    end
  end
  
  class View < R '/inbox/(\w+)/(\d+)'
    def get name,message_id
      @inbox = SpamSack::Models::Inbox.find_by_name(name.downcase)
      @message = @inbox.messages.find(message_id)
      render :view
    end
  end
  
  class InboxRSS < R '/inbox/(\S+)/rss'
    def get name
      @inbox = SpamSack::Models::Inbox.find_or_create_by_name(name.downcase)
      @headers["Content-Type"] = "text/xml"
      xml = Builder::XmlMarkup.new(:indent => 2)
      xml.rss(:version=>"2.0") do
        xml.channel do
          xml.title "SpamSack: Recent Message for #{@inbox.name}@spamsack.com"
          xml.link "http:"+URL(Inbox,@inbox.name).to_s
          @inbox.messages.each do |message|
            xml.item do 
              xml.title message.subject
              xml.link "http:"+URL(View,@inbox.name,message.id).to_s
              xml.pubDate(message.created_on)
              xml.description message.body.gsub("\n", "<br>")
            end
          end
        end
      end
    end
  end
  
  class RedirectToInbox < R '/send_to_inbox'
    def post
      if input.name == ""
        redirect R(Index)
      else
        redirect R(Inbox, input.name.downcase)
      end
    end
  end
  
end

module SpamSack::Views
  def layout
    xhtml_strict do 
      head do
        title SpamSack.config["title"]
        style do
          css = <<END
  body {
    padding: 5px;
    color: #333;
    }
  a {
    color: #06c;
  }
  h1 {color: #06c;}
  h2 {color: #98AF19;}
  fieldset {border: none;}
  div.skyscraper {
    float: right;
  }
  div.main {
    float: left;
  }
END
          css
        end
      end
      body do
        div.skyscraper do
          h3 "Meta"
          p do
            span "Developed by "
            span do 
              a :href => "http://www.michaelgorsuch.org" do
                "Michael Gorsuch."
              end
            end
          end
          p do
            span "Source code is available "
            span do
              a :href => "http://code.google.com/p/spamsack" do
                "here."
              end
            end
          end
          h3 "Our Sponsors"
          _adsense_skyscraper
        end
        h1 SpamSack.config["title"]
        h2 "Serving #{SpamSack::Models::Inbox.count} Happy Customers, and Holding #{SpamSack::Models::Message.count} Messages"

        div.main do
          #_adsense_banner
          self << yield
          #_adsense_banner
        end
      end
    end
  end
  
  def index
    div {RedCloth.new(SpamSack.config["welcome"]).to_html}
    
    form :action => R(RedirectToInbox), :method => "post" do
      fieldset do
        div do
          div do
            label {"Enter the Name of Your Inbox:"}
          end
          input :type => "input", :name => "name"
        end
        input :type => "submit", :value => "Check Mail"
      end
    end
  end
  
  def inbox
    p do
      a :href => R(Index) do
        "< Back to Home"
      end
    end
    h3 do 
      span "All Messages Sent to #{@inbox.name}@spamsack.com"
      span " "
      span do
        a :href => R(InboxRSS, @inbox.name) do
          "(rss)"
        end
      end
    end
    ul do
      @inbox.messages.each do |message|
        li do
          a :href => R(View, @inbox.name, message.id) do
            message.subject
          end
        end
      end
    end
  end
  
  def view
    p do
      a :href => R(Inbox, @inbox.name) do
        "< Back to Inbox"
      end
    end
    div.from "From: #{@message.from}"
    div.subject "Subject: #{@message.subject}"
    div.date "Date: #{@message.date}"
    p.body {@message.body.gsub("\n", "<br>")}
  end
  
  def _adsense_banner
    script :type => "text/javascript" do
      data = <<END
      <!--
      google_ad_client = "pub-8587168110609663";
      google_ad_width = 728;
      google_ad_height = 90;
      google_ad_format = "728x90_as";
      google_ad_type = "image";
      //2007-07-15: SpamSack
      google_ad_channel = "8117752467";
      google_color_border = "FFFFFF";
      google_color_bg = "FFFFFF";
      google_color_link = "0000FF";
      google_color_text = "000000";
      google_color_url = "008000";
      //-->      
END
      data
    end
    script :type => "text/javascript", :src => "http://pagead2.googlesyndication.com/pagead/show_ads.js" do
    end
  end
  
  def _adsense_skyscraper
      script :type => "text/javascript" do
        data = <<END
        <!--
        google_ad_client = "pub-8587168110609663";
        google_ad_width = 120;
        google_ad_height = 600;
        google_ad_format = "120x600_as";
        google_ad_type = "image";
        //2007-07-15: SpamSack
        google_ad_channel = "8117752467";
        google_color_border = "FFFFFF";
        google_color_bg = "FFFFFF";
        google_color_link = "0000FF";
        google_color_text = "000000";
        google_color_url = "008000";
        //-->      
END
        data
      end
      script :type => "text/javascript", :src => "http://pagead2.googlesyndication.com/pagead/show_ads.js" do
      end
    end  
  
end

module SpamSack::Models
  class Inbox < Base
    validates_presence_of :name
    has_many :messages
  end
  
  class CreateInbox < V 0.1
    def self.up
      create_table :spamsack_inboxes do |t|
        t.column :id, :integer
        t.column :name, :string
        t.column :created_on, :datetime
      end  
    end
    
    def self.down
      drop_table :spamsack_inboxes
    end 
  end
  
  class Message < Base
    validates_presence_of [:inbox, :from, :to, :date]
    belongs_to :inbox
  end
  
  class CreateMessages < V 0.2
    def self.up
      create_table :spamsack_messages do |t|
        t.column :id, :integer
        t.column :inbox_id, :integer
        t.column :from, :string
        t.column :to, :string
        t.column :subject, :string
        t.column :date, :datetime
        t.column :created_on, :datetime
        t.column :body, :text
      end
    end
    
    def self.down
      drop_table :spamsack_messages
    end
  end
  
end

def SpamSack.create
  Markaby::Builder.set(:indent, 2)
  @@config = YAML.load(File.open(File.join(File.dirname(__FILE__),"config.yml")))
  SpamSack::Models::Base.establish_connection :adapter => 'sqlite3', :database => File.join(File.dirname(__FILE__),"spamsack.db")
  SpamSack::Models.create_schema
end

def SpamSack.config
  @@config
end

class IncomingMessageHandler < ActionMailer::Base
  def receive(email)
    
    to = email.to.first
    if to.match /(\w+)@spamsack.com/
      @inbox = SpamSack::Models::Inbox.find_or_create_by_name($1)

      @message = SpamSack::Models::Message.new
      @message.inbox = @inbox
      @message.to = email.to
      @message.from = email.from
      @message.subject = email.subject
      @message.date = email.date
      @message.body = email.body
      
      if @message.save
        true
      else
        false
      end
    else
      
    end
  end
end
